%% Author: vvorobyov
%% Created: 11.03.2009
%% Description: TODO: Add description to port_test
-module(port_test).

%%
%% Include files
%%

%%
%% Exported Functions
%%
-export([start/1,init/1,call_port/1,stop/0]).

%%
%% API Functions
%%
%"java -cp D:\_Development\Erlang\wsp\bdb_host\bin com.Host"
start(Prog) ->
	spawn_link(?MODULE, init, [Prog]).

init(ExtPrg) ->
  register(complex, self()),
  process_flag(trap_exit, true),
  Port = (catch open_port({spawn, ExtPrg}, [{packet, 4}])),
  loop(Port).

loop(Port) ->
    receive
        {call, Caller, Msg} ->
            Port ! {self(), {command, encode(Msg)}},
            receive
                {Port, {data, Data}} ->
                    Caller ! {complex, decode(Data)}
            end,
            loop(Port);
        stop ->
            Port ! {self(), close},
            receive
                {Port, closed} ->
                    exit(normal)
            end;
        {'EXIT', Port, Reason} ->
            exit({port_terminated,Reason})
    end.

encode(Any) -> term_to_binary(Any);
encode(L) when is_list(L) -> L;
encode({foo, X}) -> [1, X];
encode({bar, Y}) -> [2, Y].

decode(Any) -> binary_to_term(list_to_binary(Any));
decode(L) when is_list(L) -> L;
decode([Int]) -> Int.

stop() ->
    complex ! stop.

%% foo(X) ->
%%     call_port({foo, X}).
%% bar(Y) ->
%%     call_port({bar, Y}).

call_port(Msg) ->
    complex ! {call, self(), Msg},
    receive
        {complex, Result} ->
            Result
    end.

%%
%% Local Functions
%%

